package com.young.service.impl;

import com.young.config.DirectRabbitMQConfig;
import com.young.entity.Order;
import com.young.mapper.OrderMapper;
import com.young.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private OrderMapper orderMapper;
    public String stockKey="stock:count:";

    @Override
    public Boolean saveOrder(Order order) {
        return orderMapper.insert(order)>0;
    }

    @Override
    public String seckill(Integer productId, Integer userId) {
        /**
         * 考虑情况，在我们的项目中，如果公司的redis集群突然挂掉了，应该怎么办？
         * 1. 一般会有备用的redis集群，因为公司一般会有报警系统，运维人员会在redis集群挂掉后立刻得知，对集群进行重启，若短时间无法重启成功，可使用备用的集群
         * 2. 使用rocksDB进行下单日志记录，同时不断访问集群，观察集群是否启动成功，但集群启动成功后，集群根据下单日志，扣减库存
         */
        //获取剩余库存
        Integer stock=Integer.parseInt(stringRedisTemplate.opsForValue().get(stockKey+productId));
        if (stock<=0){
            log.info("库存不足=========================");
            return "库存不足";
        }
        //扣减库存
        Long res = stringRedisTemplate.opsForValue().decrement(stockKey + productId);
        if (res<0){
            //超买了，回退
            stringRedisTemplate.opsForValue().increment(stockKey+productId);
            log.info("秒杀失败=========================");
            return "秒杀失败";
        }

        Order order=new Order();
        //生成订单id，这里应该使用雪花算法等分布式id生成算法，不过为了简单，我直接使用uuid
        order.setId(UUID.randomUUID().toString());
        order.setProductId(productId);
        order.setUserId(userId);
        //设置当前时间戳
        order.setVersion(System.currentTimeMillis());
        //存入消息队列
        rabbitTemplate.convertAndSend(DirectRabbitMQConfig.DIRECT_ORDER_EXCHANGE,
                DirectRabbitMQConfig.DIRECT_ORDER_ROUTING,order);
        log.info("秒杀成功===========================");
        return order.getId();
    }
}
